package controllerfront

import (
	"freely/bin/before"
	"freely/bin/crud"
	"freely/src/constant"
	modelfront "freely/src/model/front"
	sourcelogin "freely/src/source/login"
	"net/http"
	"strconv"
	"time"

	"github.com/gin-contrib/i18n"
	"github.com/gin-gonic/gin"
)

type ControllerFrontLogin struct {
	*crud.Controller
}

var loginClass *sourcelogin.SourceLoginer
var expireTime = time.Hour * 2

func init() {
	loginClass = sourcelogin.NewSourceLoginer()
}

// 登录
func (c *ControllerFrontLogin) Login(ctx *gin.Context) {
	var params = &modelfront.LoginParams{}
	if err := ctx.ShouldBindJSON(params); err != nil {
		ctx.JSON(http.StatusOK, before.ReqFail(ctx, err.Error()))
		return
	}

	if !loginClass.CaptchaVerify(params.CaptchaId, params.VerifyCode) {
		ctx.JSON(http.StatusOK, before.ReqFail(ctx, "login.captchaErr"))
		return
	}

	loginAt := ctx.GetString(constant.AuthFromTo)

	res, err := loginClass.SourceLogin(params.Username, params.Password, loginAt, expireTime)
	if err != nil {
		ctx.JSON(http.StatusOK, before.ReqFail(ctx, err.Error()))
		return
	}

	ctx.JSON(http.StatusOK, before.ReqOk(ctx, res))
}

// 注册
func (c *ControllerFrontLogin) RegisterUser(ctx *gin.Context) {
	var params = &modelfront.LoginParams{}
	if err := ctx.ShouldBindJSON(params); err != nil {
		ctx.JSON(http.StatusOK, before.ReqFail(ctx, err.Error()))
		return
	}
	var user = &modelfront.FrontUserStu{
		Username: params.Username,
		Password: params.Password,
	}
	err := loginClass.SourceRegisterUser(user)
	if err != nil {
		ctx.JSON(http.StatusOK, before.ReqFail(ctx, err.Error()))
		return
	}
	ctx.JSON(http.StatusOK, before.ReqOk(ctx, i18n.MustGetMessage(ctx, "login.registerUser")))
}

// 验证码
func (c *ControllerFrontLogin) Captcha(ctx *gin.Context) {
	w := ctx.DefaultQuery("width", "120")
	h := ctx.DefaultQuery("height", "40")

	width, err := strconv.Atoi(w)
	if err != nil {
		ctx.JSON(http.StatusBadRequest, before.ReqFail(ctx, "width.type.err"))
		return
	}
	height, err := strconv.Atoi(h)
	if err != nil {
		ctx.JSON(http.StatusBadRequest, before.ReqFail(ctx, "height.type.err"))
		return
	}

	code, err := loginClass.CaptchaCreate(width, height)
	if err != nil {
		ctx.JSON(http.StatusOK, before.ReqFail(ctx, err.Error()))
		return
	}
	ctx.JSON(http.StatusOK, before.ReqOk(ctx, *code))
}

func RegisterControllerFrontLogin(router *gin.RouterGroup) {
	var controller = &ControllerFrontLogin{
		&crud.Controller{
			Module: modelfront.ModelName,
			Source: loginClass,
		},
	}

	var extendApi = map[string]*crud.RouterItem{
		"/login":    {From: crud.RouterPost, Call: controller.Login},
		"/register": {From: crud.RouterPost, Call: controller.RegisterUser},
		"/captcha":  {From: crud.RouterGet, Call: controller.Captcha},
	}

	crud.RegisterController(router, controller, nil, extendApi)
}
